package com.gitee.ywj1352.config;

import com.gitee.ywj1352.client.RpcClientInvoker;
import com.gitee.ywj1352.client.RpcxClient;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;

public class RpcxClinetBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class clazz = bean.getClass();
        processFields(bean, clazz.getDeclaredFields());
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * 装配 bean
     * @param bean
     * @param declaredFields
     */
    private void processFields(Object bean, Field[] declaredFields) {
        for (Field field : declaredFields) {
            RpcxClient annotation = AnnotationUtils.getAnnotation(field, RpcxClient.class);
            if (annotation == null) {
                continue;
            }
            Class<?> type = field.getType();
            RpcxProxyConfig rpcxProxyConfig = new RpcxProxyConfig();
            rpcxProxyConfig.setClassName(type.getSimpleName());
            rpcxProxyConfig.setServiceId(annotation.serverId());
            Object proxy = null;
            try {
                proxy = RpcClientInvoker.createProxy(type, rpcxProxyConfig);
                ReflectionUtils.makeAccessible(field);
                ReflectionUtils.setField(field, bean, proxy);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
    }

}
